昨天我們講到資料模型產生器的用法:
rails generate model keyword_mapping keyword message
會產生兩個我們需要的檔案:
db/migrate/20180110181744_create_keyword_mappings.rb
app/models/keyword_mapping.rb
其中,資料庫遷移檔就像是一張對資料庫施法的卷軸設計圖,可以用來幫資料庫升級。
那要怎麼升級呢?
使用 rails db:migrate
指令就會進行資料庫升級。
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate
== 20180110181744 CreateKeywordMappings: migrating ============================
-- create_table(:keyword_mappings)
-> 0.4916s
== 20180110181744 CreateKeywordMappings: migrated (0.4927s) ===================
D:\只要有心,人人都可以作卡米狗\ironman>
還可以用 rails db:rollback
降級:
D:\只要有心,人人都可以作卡米狗\ironman>rails db:rollback
== 20180110181744 CreateKeywordMappings: reverting ============================
-- drop_table(:keyword_mappings)
-> 0.5057s
== 20180110181744 CreateKeywordMappings: reverted (0.5211s) ===================
D:\只要有心,人人都可以作卡米狗\ironman>
可以用 rails db:migrate:status
查看目前等級。這是升級前:
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate:status
database: D:/只要有心,人人都可以作卡米狗/ironman/db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
down 20180110181744 Create keyword mappings
D:\只要有心,人人都可以作卡米狗\ironman>
這是升級後:
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate:status
database: D:/只要有心,人人都可以作卡米狗/ironman/db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20180110181744 Create keyword mappings
D:\只要有心,人人都可以作卡米狗\ironman>
資料庫已就緒,接下來就只等我們把學習紀錄寫入了。接下來我會試著用 Google 試算表來比喻目前資料庫的狀態(因為我家沒有 Excel),現在的資料庫看起來像這樣:
我們可以使用 rails console
或簡寫 rails c
去試著操作看看資料模型, rails console
是一個類似 irb
的互動式介面,他可以讓你輸入一行程式就立即生效。
D:\只要有心,人人都可以作卡米狗\ironman>rails console
Loading development environment (Rails 5.1.4)
irb(main):001:0>
我們的資料模型叫做 KeywordMapping
。可以用 .all
將它顯示出來看看:
irb(main):001:0> KeywordMapping.all
KeywordMapping Load (2.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
irb(main):002:0>
這一段:
SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ?
是我們對資料庫進行查詢的 SQL 語法,幸好你不需要學會這個,就當作沒看到吧。
而這一段:
=> #<ActiveRecord::Relation []>
是指 KeywordMapping.all
是一個 ActiveRecord::Relation
類別的實體, []
表示它是空的。
讓我們弄點東西進去。
用 KeywordMapping.new
可以獲得一筆新的空白資料。因為我們接下來要對他做點事情,所以用一個變數 new_data
去接住它。
我們要寫的是 new_data = KeywordMapping.new
。
irb(main):002:0> new_data = KeywordMapping.new
=> #<KeywordMapping id: nil, keyword: nil, message: nil, created_at: nil, updated_at: nil>
irb(main):003:0>
接下來設定 new_data 的 keyword 是 "Q"。
irb(main):003:0> new_data.keyword = "Q"
=> "Q"
設定 new_data 的 message 是 "A"。
irb(main):004:0> new_data.message = "A"
=> "A"
irb(main):005:0>
都設定好之後用 new_data.save
來存檔。
irb(main):005:0> new_data.save
(0.0ms) begin transaction
SQL (494.1ms) INSERT INTO "keyword_mappings" ("keyword", "message", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["keyword", "Q"], ["message", "A"], ["created_at", "2018-01-11 14:30:55.567172"], ["updated_at", "2018-01-11 14:30:55.567172"]]
(52.5ms) commit transaction
=> true
irb(main):006:0>
一樣,就是一堆不需要看懂的 SQL。現在使用 KeywordMapping.all
就能看到新加入的資料了。
目前資料表的狀態:
irb(main):006:0> KeywordMapping.all
KeywordMapping Load (0.0ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<KeywordMapping id: 1, keyword: "Q", message: "A", created_at: "2018-01-11 14:30:55", updated_at: "2018-01-11 14:30:55">]>
irb(main):007:0>
新增資料也有簡寫的方式可以一行做完,指令是 KeywordMapping.create({keyword:"Q2", message:"A2"})
:
irb(main):007:0> KeywordMapping.create(keyword:"Q2", message:"A2")
(0.0ms) begin transaction
SQL (485.4ms) INSERT INTO "keyword_mappings" ("keyword", "message", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["keyword", "Q2"], ["message", "A2"], ["created_at", "2018-01-11 14:36:34.858893"], ["updated_at", "2018-01-11 14:36:34.858893"]]
(48.5ms) commit transaction
=> #<KeywordMapping id: 2, keyword: "Q2", message: "A2", created_at: "2018-01-11 14:36:34", updated_at: "2018-01-11 14:36:34">
irb(main):008:0>
這是傳入一個 hash 作為設定,用 create
方法的話就會自動 save
,所以就不用自己再打 save
了。
目前資料表的狀態:
irb(main):009:0> KeywordMapping.all
KeywordMapping Load (0.0ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<KeywordMapping id: 1, keyword: "Q", message: "A", created_at: "2018-01-11 14:30:55", updated_at: "2018-01-11 14:30:55">, #<KeywordMapping id: 2, keyword: "Q2", message: "A2", created_at: "2018-01-11 14:36:34", updated_at: "2018-01-11 14:36:34">]>
irb(main):010:0>
我們通常不會想要拿出整個資料表,而是只想要查當中的一筆,這時候就要用 where
方法,以下示範 KeywordMapping.where(keyword:"Q2")
。
irb(main):008:0> KeywordMapping.where(keyword:"Q2")
KeywordMapping Load (0.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" WHERE "keyword_mappings"."keyword" = ? LIMIT ? [["keyword", "Q2"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<KeywordMapping id: 2, keyword: "Q2", message: "A2", created_at: "2018-01-11 14:36:34", updated_at: "2018-01-11 14:36:34">]>
irb(main):009:0>
這是篩選功能,我們對 keyword
欄位做 Q2
篩選,在 Google 試算表按照順序點就可以達到相同的效果。
篩選出來可能會有多筆,我們可以 .all
取得全部或者 .first
取第一筆,或 .last
取最後一筆。
所以卡米狗觸發教學的寫法是這樣:KeywordMapping.where(keyword:"Q2").last.message
,對 keyword
欄位做篩選,找到最後一次教學紀錄,然後取出 message
欄位的內容。
irb(main):012:0* KeywordMapping.where(keyword:"Q2").last.message
KeywordMapping Load (0.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" WHERE "keyword_mappings"."keyword" = ? ORDER BY "keyword_mappings"."id" DESC LIMIT ? [["keyword", "Q2"], ["LIMIT", 1]]
=> "A2"
irb(main):013:0>
丟 Q2 進去資料庫查,查到 A2 再回應給 Line。
明天會講怎麼用這兩天學到的東西做出卡米狗學習指令。
用一個變數 new_data 去接住它,因為我們接下來要對他做事。
但是KEY好像無法新增...
請問該如何解決~感恩!!
因為你要寫的是 new_data = KeywordMapping.new
如果是只寫 KeywordMapping.new
的話,新的資料就會直接消失在空氣中
我修改一下本文
好的~我再試試!!感恩教學><
請問一下
在irb寫KeywordMapping.all
是否可以直接寫成SELECT * FROM KeywordMapping;
這邊是可以直接寫SQL語法的嗎?(假設其實對SQL語法比較熟悉)
我在下rails c的時候遇到了以下錯誤
試試看這個方法:
去 C:\Users\<username>\
找一個叫做 .irb_history
的檔案,然後把它刪了。
成功進去了,謝謝!
資料庫遷移
使用 rails db:migrate 指令就會進行資料庫升級。
使用 rails db:rollback 指令就會進行資料庫升級。
我使用的時候出現這樣的錯誤...
這意思是連線主機端在我本機端嗎?
看起來是你的本機電腦沒有 postgresql,所以無法。
不過在我提供的教學裡面有說到要在本機使用 sqlite3
我有設定呀,可是他還是給出這樣的錯誤,我的測試環境設定長這樣
請問方便用mail問您嗎 哈哈:),因為最近在學ruby其實有很多語法看不懂
你的設定檔是錯的,關於學 ruby 可以參考 https://railsbook.tw/
謝謝,我重新再去看一次設定檔的部分真的有少
現在已經過這關了:)
卡卡米大大安安
不小心把資料庫弄亂了...我嘗試過 --force 指令
rails generate model id_name_data user_id user_name channel_id channel_name channel_master --force
雖然可以成功建立 資料庫模型 ,但做資料庫升級時 還是一直出現錯誤...
C:\Users\Nien\Desktop\nien_love_kamigo\ironman>rails db:migrate
== 20180221012538 CreateChannelStatuses: migrating ============================
-- create_table(:channel_statuses)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "channel_statuses" already exists: CREATE TABLE "ch
annel_statuses" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "channel_id" v
archar, "status_text" varchar, "coordinates_status" varchar, "separation_coordin
ates" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
C:/Users/Nien/Desktop/nien_love_kamigo/ironman/db/migrate/20180221012538_create_
channel_statuses.rb:3:in change' bin/rails:4:in
require'
bin/rails:4:in `'
Caused by:
ActiveRecord::StatementInvalid: SQLite3::SQLException: table "channel_statuses"
already exists: CREATE TABLE "channel_statuses" ("id" INTEGER PRIMARY KEY AUTOIN
CREMENT NOT NULL, "channel_id" varchar, "status_text" varchar, "coordinates_stat
us" varchar, "separation_coordinates" varchar, "created_at" datetime NOT NULL, "
updated_at" datetime NOT NULL)
C:/Users/Nien/Desktop/nien_love_kamigo/ironman/db/migrate/20180221012538_create_
channel_statuses.rb:3:in change' bin/rails:4:in
require'
bin/rails:4:in `'
Caused by:
SQLite3::SQLException: table "channel_statuses" already exists
C:/Users/Nien/Desktop/nien_love_kamigo/ironman/db/migrate/20180221012538_create_
channel_statuses.rb:3:in change' bin/rails:4:in
require'
bin/rails:4:in `'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
翻譯後,感覺是 資料表已經存在...
我就想說,刪掉檔案看看...
後來想用資料庫 降級 ,發現也已經 回不去了
目前狀態
C:\Users\Nien\Desktop\nien_love_kamigo\ironman>rails db:migrate:status
database: C:/Users/Nien/Desktop/nien_love_kamigo/ironman/db/development.sqlite3
up 20180126121210 Create keyword mappings
up 20180127055933 Create receiveds
up 20180127060449 Create replies
up 20180127065752 Add channel id to keyword reply
up 20180127081529 Devise create users
up 20180127091707 Create channels
up 20180210155702 ********** NO FILE **********
up 20180215045942 ********** NO FILE **********
up 20180220133333 ********** NO FILE **********
down 20180221012538 Create channel statuses
down 20180221012545 Create id name data
不知道現在該怎麼處裡 @@"
嘗試了 rails generate migration DropCategoriesTable
以及drop_table :id_name_data
和rake db:migrate
反覆試了好幾次 終於解決了
但卻出現另一個問題
(PG::InsufficientPrivilege: ERROR: permission denied for relation channels
說我權限不夠....
還在努力測試中~~~
試了很久 還是沒解決....
我重新移除在建立 還是一樣
這是 第二十九天 建立的 發公告 資料表
ler.rb:13 錯誤 無發新增頻道
# 紀錄頻道
Channel.find_or_create_by(channel_id: channel_id)
2018-02-21T08:45:02.050578+00:00 app[web.1]: I, [2018-02-21T08:45:02.050498 #4]
INFO -- : [ffeadee0-6789-479b-aa62-83c3b3566892] Parameters: {"events"=>[{"ty
pe"=>"message", "replyToken"=>"192cf4644dc040dfb10f50043991d126", "source"=>{"gr
oupId"=>"C894501bbd95a7fe433157263b35ab388", "userId"=>"U6d45c09d594a63ea1623937
dbebed64c", "type"=>"group"}, "timestamp"=>1519202701448, "message"=>{"type"=>"t
ext", "id"=>"7510428366336", "text"=>"測試一下"}}], "kamigo"=>{"events"=>[{"type
"=>"message", "replyToken"=>"192cf4644dc040dfb10f50043991d126", "source"=>{"grou
pId"=>"C894501bbd95a7fe433157263b35ab388", "userId"=>"U6d45c09d594a63ea1623937db
ebed64c", "type"=>"group"}, "timestamp"=>1519202701448, "message"=>{"type"=>"tex
t", "id"=>"7510428366336", "text"=>"測試一下"}}]}}
2018-02-21T08:45:02.051062+00:00 app[web.1]: W, [2018-02-21T08:45:02.050988 #4]
WARN -- : [ffeadee0-6789-479b-aa62-83c3b3566892] Can't verify CSRF token authen
ticity.
2018-02-21T08:45:02.054790+00:00 app[web.1]: D, [2018-02-21T08:45:02.054700 #4]
DEBUG -- : [ffeadee0-6789-479b-aa62-83c3b3566892] Channel Load (0.7ms) SELECT
"channels".* FROM "channels" WHERE "channels"."channel_id" = $1 LIMIT $2 [["c
hannel_id", "C894501bbd95a7fe433157263b35ab388"], ["LIMIT", 1]]
2018-02-21T08:45:02.056997+00:00 app[web.1]: D, [2018-02-21T08:45:02.056173 #4]
DEBUG -- : [ffeadee0-6789-479b-aa62-83c3b3566892] (0.7ms) BEGIN
2018-02-21T08:45:02.061163+00:00 app[web.1]: D, [2018-02-21T08:45:02.061072 #4]
DEBUG -- : [ffeadee0-6789-479b-aa62-83c3b3566892] SQL (1.8ms) INSERT INTO "ch
annels" ("channel_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING
"id" [["channel_id", "C894501bbd95a7fe433157263b35ab388"], ["created_at", "201
8-02-21 08:45:02.057203"], ["updated_at", "2018-02-21 08:45:02.057203"]]
2018-02-21T08:45:02.062234+00:00 app[web.1]: D, [2018-02-21T08:45:02.062160 #4]
DEBUG -- : [ffeadee0-6789-479b-aa62-83c3b3566892] (0.8ms) ROLLBACK
2018-02-21T08:45:02.062543+00:00 app[web.1]: I, [2018-02-21T08:45:02.062471 #4]
INFO -- : [ffeadee0-6789-479b-aa62-83c3b3566892] Completed 401 Unauthorized in
12ms (ActiveRecord: 4.0ms)
2018-02-21T08:45:02.063991+00:00 app[web.1]: F, [2018-02-21T08:45:02.063818 #4]
FATAL -- : [ffeadee0-6789-479b-aa62-83c3b3566892]
2018-02-21T08:45:02.064095+00:00 app[web.1]: F, [2018-02-21T08:45:02.064025 #4]
FATAL -- : [ffeadee0-6789-479b-aa62-83c3b3566892] ActiveRecord::StatementInvalid
(PG::InsufficientPrivilege: ERROR: permission denied for relation channels
2018-02-21T08:45:02.064098+00:00 app[web.1]: : INSERT INTO "channels" ("channel_
id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"):
2018-02-21T08:45:02.064186+00:00 app[web.1]: F, [2018-02-21T08:45:02.064122 #4]
FATAL -- : [ffeadee0-6789-479b-aa62-83c3b3566892]
2018-02-21T08:45:02.064320+00:00 app[web.1]: F, [2018-02-21T08:45:02.064250 #4]
FATAL -- : [ffeadee0-6789-479b-aa62-83c3b3566892] app/controllers/kamigo_control
ler.rb:13:in `webhook'
在做 generate model 或 generate migration 時都會產生對應的 migration 檔案,這些檔案會組成你的資料庫,如果你檢查你的 migration 檔案有重複的內容,那就得先刪除掉。
然後你可以重建資料庫,本機的資料庫想要重建的話直接把 db 資料夾下的 .sqlite3 檔案刪除就可以
heroku 上的資料庫重建可以試試看heroku pg:reset
這個指令
真的是太神了~~ 感恩卡米 讚嘆卡米~~
heroku pg:reset 之後,清空所有資料
一切都恢復正常了~~
最近有發現,之前資料庫沒寫入權限 應該也是因為 資料庫爆了
75,397 of 10,000
ROWS WRITE ACCESS REVOKED
21.7 MB
DATA SIZE
以前都沒注意到HEROKU的貼心提醒
Mar 14 at 4:36 PM
[warning] Database disruption imminent, row limit exceeded for hobby-dev database on Heroku app nienmesh
The database DATABASE_URL on Heroku app nienmesh has exceeded its allocated storage capacity. Immediate action is required.
The database contains 10,289 rows, exceeding the Hobby-dev plan limit of 10,000. INSERT privileges to the database will be automatically revoked in 7 days. This will cause service failures in most applications dependent on this database.
To avoid a disruption to your service, migrate the database to a Hobby Basic ($9/month) or higher database plan:
https://devcenter.heroku.com/articles/upgrade-heroku-postgres-with-pgbackups
If you are unable to upgrade the database, you should reduce the number of records stored in it.
哇 免費額度用完了,其實你可以考慮把對話紀錄拔掉或者寫程式刪除舊的對話紀錄,這樣就不會吃太多資料庫空間
哇 免費額度用完了,其實你可以考慮把對話紀錄拔掉或者寫程式刪除舊的對話紀錄,這樣就不會吃太多資料庫空間
恩恩 有爬文找刪除資料表的方式
試了好幾種方式 也試很多次 終於刪掉了
但不確定是哪一次的方式 才成功的
我先記錄起來 下次資料庫滿了 在試一次
我有在思考 怎麼改寫程式 讓他記憶最近5筆就好
第6筆 會先刪掉第一筆
明天再繼續測試 呵呵
卡米大大好
最近有再嘗試寫 記錄最後一次發言的程式
但這個記錄量感覺很龐大...
後來有發現,退群時,沒有清空該群組記錄.. 是導致資料庫旁大的原因之一...
我目前是建一個資料庫 群組ID 使用者ID 入群時間 上次發言時間
印象中資料庫本身就有 創建時間 和更新時間
我還在仔細研究 怎麼寫指令 管理資料庫
(目前都是到網頁上 一個一個刪除... 好累人...)
您好卡卡米大,
目前學習到這邊卡住,
輸入KeywordMapping.all後,會出現no such table,
是指說找不到資料庫嗎?請問這該如何解???
https://imgur.com/a/85c4W
你漏了這個
rails db:migrate
感謝,犯蠢資料庫升級後又把它降級@@
請問卡米大大
我在一開始創造 keyword_mapping 這個資料表的時候,不小心把 message 打成 messaage,就變成這樣
我有試過在 Sublime Text 裡面將 keyword_mapping 的檔案都刪掉然後再創一個正確的,但他還是以我一開始創的為主,請問有辦法改回來嗎?不然我就要一直打 messaage 了 @@
我們會使用 rails db:migrate 來讓這個檔案幫我們控制資料庫,如果你只是單純修改這個檔案,而沒有下對應指令的話,資料庫會維持原樣。
比較簡單的方法是把資料庫檔案刪除重建一個。
比較複雜的方法是使用 rails db:rollback 讓資料庫回到還沒有執行 rails db:migrate 的狀態,然後再下 rails db:migrate 讓他重跑
不管你用哪一種方法,你的 keyword_mappings 資料都會遺失。
如果要確保資料不遺失,你可以再另外新增一個 migration 檔案來做修改命名,細節你可以參考這篇文章 https://ihower.tw/rails/migrations.html 中的 rename_column
我用了 rails db:rollback 還有 rails db:migrate (以下是執行的圖片)
但我在最後新增資料表時,他還是一樣寫 messaage,是不是我理解錯了
疑 好像漏回了
不過,你在 rollback 重新 migrate 的時候有修改 migration 檔案了嗎?
跪求卡米大幫忙
我嘗試自己找問題
發現我的rails版本跟卡米大的不一樣
然後我的db檔案好像也會不一樣
然後我試試看用new_data.key = "Q"
發現是可行的
然而new_data.keyword = "Q"也就是卡米大用的
會出現NoMethodError: undefined method `keyword=' for #KeywordMapping:0x00000000067efb20的問題
可是new_data.message = "A"這裡就找不到方法替代了
去網路上找發現全部都是英文看不懂
希望卡米大可以幫忙謝謝!
看起來是你的 migration 檔案有問題,可能是在你下生成語法的時候打錯字了。
最簡單的修正方法是刪掉你的資料庫,修改好你的 migration 檔,再重建資料庫。
嗯嗯問題已經成功解決
謝謝卡米大
方便的話可以教我更多的功能嗎